const PIPELINES = [
{
id: 'swenc-dmabuf-vp8-vp8enc',
+ fileExtension: 'webm',
pipelineString:
'capsfilter caps=video/x-raw(memory:DMABuf),max-framerate=%F/1 ! \
glupload ! glcolorconvert ! gldownload ! \
},
{
id: 'swenc-memfd-vp8-vp8enc',
+ fileExtension: 'webm',
pipelineString:
'capsfilter caps=video/x-raw,max-framerate=%F/1 ! \
videoconvert chroma-mode=none dither=none matrix-mode=output-only n-threads=%T ! \
};
class Recorder extends Signals.EventEmitter {
- constructor(sessionPath, x, y, width, height, filePath, options,
+ constructor(sessionPath, x, y, width, height, filePathStem, options,
invocation) {
super();
this._y = y;
this._width = width;
this._height = height;
- this._filePath = filePath;
+ this._filePathStem = filePathStem;
try {
- const dir = Gio.File.new_for_path(filePath).get_parent();
+ const dir = Gio.File.new_for_path(filePathStem).get_parent();
dir.make_directory_with_parents(null);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS))
}
_tryNextPipeline() {
+ if (this._filePath) {
+ GLib.unlink(this._filePath);
+ delete this._filePath;
+ }
+
const {done, value: pipelineConfig} = this._pipelineConfigs.next();
if (done) {
this._handleFatalPipelineError('All pipelines failed to start',
newState === Gst.State.PLAYING) {
this._pipelineState = PipelineState.PLAYING;
- this._startRequest.resolve();
+ this._startRequest.resolve(this._filePath);
delete this._startRequest;
}
}
_createPipeline(nodeId, pipelineConfig, framerate) {
- const {pipelineString} = pipelineConfig;
+ const {fileExtension, pipelineString} = pipelineConfig;
const finalPipelineString = this._substituteVariables(pipelineString, framerate);
+ this._filePath = `${this._filePathStem}.${fileExtension}`;
const fullPipeline = `
pipewiresrc path=${nodeId}
let filename = '';
let escape = false;
+ // FIXME: temporarily detect and strip .webm prefix to avoid breaking
+ // external consumers of our API, remove this again
+ if (template.endsWith('.webm')) {
+ console.log("'file_template' for screencast includes '.webm' file-extension. Passing the file-extension as part of the filename has been deprecated, pass the 'file_template' without a file-extension instead.");
+ template = template.substring(0, template.length - '.webm'.length);
+ }
+
[...template].forEach(c => {
if (escape) {
switch (c) {
const [fileTemplate, options] = params;
const [screenWidth, screenHeight] = this._introspectProxy.ScreenSize;
- const filePath = this._generateFilePath(fileTemplate);
+ const filePathStem = this._generateFilePath(fileTemplate);
let recorder;
sessionPath,
0, 0,
screenWidth, screenHeight,
- filePath,
+ filePathStem,
options,
invocation);
} catch (error) {
this._addRecorder(sender, recorder);
try {
- await recorder.startRecording();
- invocation.return_value(GLib.Variant.new('(bs)', [true, filePath]));
+ const pathWithExtension = await recorder.startRecording();
+ invocation.return_value(GLib.Variant.new('(bs)', [true, pathWithExtension]));
} catch (error) {
log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender);
const [sessionPath] = this._proxy.CreateSessionSync({});
const [x, y, width, height, fileTemplate, options] = params;
- const filePath = this._generateFilePath(fileTemplate);
+ const filePathStem = this._generateFilePath(fileTemplate);
let recorder;
sessionPath,
x, y,
width, height,
- filePath,
+ filePathStem,
options,
invocation);
} catch (error) {
this._addRecorder(sender, recorder);
try {
- await recorder.startRecording();
- invocation.return_value(GLib.Variant.new('(bs)', [true, filePath]));
+ const pathWithExtension = await recorder.startRecording();
+ invocation.return_value(GLib.Variant.new('(bs)', [true, pathWithExtension]));
} catch (error) {
log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender);